package com.example.design.shejimoshi.action.expression.improve01;

import java.util.Deque;
import java.util.LinkedList;

/**
 * @Description TODO
 * @date 2022/11/11 16:42
 * @Author liuzhihui
 * @Version 1.0
 */
public class ExpressionInterpreter {
    private static Deque<Expression> numbers = new LinkedList<>();

    public static long interpret(String expression) {
        String[] elements = expression.split(" ");
        int length = elements.length;

        for (int i = 0; i < (length + 1) / 2; i++) {
            numbers.addLast(new NumberExpression(elements[i]));
        }

        for (int i = (length + 1) / 2; i < length; i++) {
            String operator = elements[i];

            boolean isValid = "+".equals(operator) || "-".equals(operator) || "*".equals(operator) || "/".equals(operator);
            if (!isValid) {
                throw new RuntimeException("Expression is invalid: " + expression);
            }

            Expression expression1 = numbers.pollFirst();
            Expression expression2 = numbers.pollFirst();

            // 语法规则的解析逻辑
            Expression combinedExp = null;
            if (operator.equals("+")) {
                combinedExp = new AdditionExpression(expression1, expression2);
            } else if (operator.equals("-")) {
                combinedExp = new SubstractionExpression(expression1, expression2);
            } else if (operator.equals("*")) {
                combinedExp = new MultiplicationExpression(expression1, expression2);
            } else if (operator.equals("/")) {
                combinedExp = new DivisionExpression(expression1, expression2);
            }
            long result = combinedExp.interpret();
            numbers.addFirst(new NumberExpression(result));
        }

        if (numbers.size() != 1) {
            throw new RuntimeException("Expression is invalid：" + expression);
        }

        return numbers.pop().interpret();
    }
    public static void main(String[] args) {
        long interpret = interpret("8 3 2 4 - + *");
        System.out.println(interpret);
    }

}
